#include <iostream>
#include "dal_fastrtps_cpp/type_support_common.hpp"
#include "my_package/msg/all_type.hpp"

extern "C" {
extern const dalidl_message_type_support_t*
dalidl_typesupport_fastrtps_cpp__get_message_type_support_handle__my_package__msg__AllType();
}

int main()
{
    // create msg and set msg.
    my_package::msg::AllType msg;
    msg.str = "AllType";
    msg.unbound_u8_arr = std::vector<uint8_t>(100, 8);
    msg.under.name = "AllTypeUnder";
    msg.under.un_int_arr = std::vector<int32_t>(1, 8);

    // use rmw_fastdds typesupport mechanism to serialize msg.
    const dalidl_message_type_support_t* ts_handle_ =
        dalidl_typesupport_fastrtps_cpp__get_message_type_support_handle__my_package__msg__AllType();
    auto callbacks = static_cast<const message_type_support_callbacks_t*>(ts_handle_->data);
    auto mts = new MessageTypeSupport_cpp(callbacks);

    auto estimated_size = mts->getEstimatedSerializedSize(&msg, callbacks);
    std::cout << "estimate msg size: " << estimated_size << std::endl;

    eprosima::fastrtps::rtps::SerializedPayload_t payload;
    payload.reserve(estimated_size * 2);
    eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast<char*>(payload.data),
                                             payload.max_size);
    eprosima::fastcdr::Cdr ser(
        fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN, eprosima::fastcdr::Cdr::DDS_CDR);
    if (mts->serializeROSmessage(&msg, ser, callbacks)) {
        payload.encapsulation =
            ser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE;
        payload.length = (uint32_t)ser.getSerializedDataLength();

        std::cout << "serialize msg size: " << payload.length << std::endl;
    }

    // deserialize msg.
    my_package::msg::AllType msg_deserialized;

    eprosima::fastcdr::FastBuffer fastbuffer2(reinterpret_cast<char*>(payload.data),
                                              payload.length);
    eprosima::fastcdr::Cdr deser(
        fastbuffer2, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN, eprosima::fastcdr::Cdr::DDS_CDR);
    if (mts->deserializeROSmessage(deser, &msg_deserialized, callbacks)) {
        std::cout << "deserialize msg succeed:\n"
                  << "\tstr : " << msg_deserialized.str << "\n"
                  << "\tunbound_u8_arr.size : " << msg_deserialized.unbound_u8_arr.size() << "\n"
                  << "\tunbound_u8_arr[0] : " << (int)(msg_deserialized.unbound_u8_arr[0]) << "\n"
                  << "\tunder.name : " << msg_deserialized.under.name << "\n"
                  << "\tunder.un_int_arr.size : " << msg_deserialized.under.un_int_arr.size() << "\n"
                  << "\tunder.un_int_arr[0] : " << msg_deserialized.under.un_int_arr[0] << std::endl;
    }

    return 0;
}
